#include "FilterDialog.h"
#include <QMessageBox>
#include <QGenericMatrix>
#include "FilterLinear.h"
#include "BoxCoreGenerator.h"
#include "GaussCoreGenerator.h"
#include "SobelCoreGenerator.h"
#include "PrewittCoreGenerator.h"
#include "RobertCoreGenerator.h"



// Box, Gauss, Sobel, Prewitt, Roberts
FilterDialog::FilterDialog (QWidget *parent)
: AbstractDialog (parent)
{
	ui.setupUi(this);
	ui.cbCorePreset->addItem (tr("Custom"));
	ui.cbCorePreset->addItem (tr("Box"));
	ui.cbCorePreset->addItem (tr("Gauss"));
	ui.cbCorePreset->addItem (tr("Sobel_X"));
	ui.cbCorePreset->addItem (tr("Sobel_Y"));
	ui.cbCorePreset->addItem (tr("Prewitt_X"));
	ui.cbCorePreset->addItem (tr("Prewitt_Y"));
	ui.cbCorePreset->addItem (tr("Roberts_1"));
	ui.cbCorePreset->addItem (tr("Roberts_2"));
}



FilterDialog::~FilterDialog ()
{

}



void FilterDialog::_openEvent ()
{
	_pCurAction = new LinearFilterAction;
	__pWork->getDoc ()->openPreview (_pCurAction.cvt< AbstractAction > ());
	_pCurAction->startAction (__pWork);
	_pCurAction->setFilterMethod (new FilterLinear (Core< float > ()));
	ui.cbCorePreset->setCurrentIndex (0);
}



void FilterDialog::_closeEvent (int r)
{
	if (r == QDialog::Accepted)
		_pCurAction->applyAction ();
	else
		_pCurAction->rejectAction ();
	__pWork->getDoc ()->closePreview ();
	emit repaintViewport ();
}

void FilterDialog::corePresetSelected (int presetIndex)
{
	Core< float > core;
	switch (presetIndex)
	{
	case 1:
		core = BoxCoreGenerator ().getCore (ui.sldCoreSize->value ());
		ui.sldCoreSize->setEnabled (true);
		break;
	case 2:
		core = GaussCoreGenerator ().getCore (ui.sldCoreSize->value ());
		ui.sldCoreSize->setEnabled (true);
		break;
	case 3:
		core = SobelCoreGenerator ().getCore (-1, 0);
		ui.sldCoreSize->setEnabled (false);
		break;
	case 4:
		core = SobelCoreGenerator ().getCore (-1, 1);
		ui.sldCoreSize->setEnabled (false);
		break;
	case 5:
		core = PrewittCoreGenerator ().getCore (-1, 0);
		ui.sldCoreSize->setEnabled (false);
		break;
	case 6:
		core = PrewittCoreGenerator ().getCore (-1, 1);
		ui.sldCoreSize->setEnabled (false);
		break;
	case 7:
		core = RobertCoreGenerator ().getCore (-1, 0);
		ui.sldCoreSize->setEnabled (false);
		break;
	case 8:
		core = RobertCoreGenerator ().getCore (-1, 1);
		ui.sldCoreSize->setEnabled (false);
		break;
	default:
		ui.sldCoreSize->setEnabled (false);
		return;
	}

	QString strCore;
	for (int i = 0; i < core.getSize ().width (); ++i) {
		for (int j = 0; j < core.getSize ().height (); ++j) {
			strCore += QString ("%1").arg ((double)core (i, j), 0, 'g', 4);
			strCore += " ";
		}
		strCore += "\n";
	}
	ui.txCore->setText (strCore);
}

void FilterDialog::coreSizeChanged (int size)
{
	ui.lbCoreSize->setText (QString ("%1").arg (size));
	corePresetSelected (ui.cbCorePreset->currentIndex ());
}

void FilterDialog::coreChanged ()
{
	vector< float > numbers;
	QString strStructElem = ui.txCore->toPlainText ();

	QStringList rows = strStructElem.split ('\n');
	int rowNum = 0;
	int columnNum = -1;

	for (QStringList::iterator i = rows.begin(); i != rows.end(); ++i)
	{
		if (i->isEmpty ()) continue;
		QStringList aRow = i->split (' ');
		++rowNum;
		int curColumns = 0;
		int pos = numbers.size ();
		numbers.push_back (0);
		for (QStringList::iterator j = aRow.begin(); j != aRow.end(); ++j)
		{
			if (j->isEmpty ()) continue;
			bool isFloat = false;
			float number = j->toFloat (&isFloat);
			if (!isFloat)
				return;
			numbers.push_back (number);
			++curColumns;
		}
		numbers[pos] = curColumns;
		if (columnNum < curColumns) columnNum = curColumns;
	}

	if (rowNum == 0 || columnNum == 0)
		return;

	Core< float > core (QSize (columnNum, rowNum), 
		QPoint (columnNum / 2, rowNum / 2));
	int index = 0;
	int numberLeftCurLine = 0;
	for (int j = 0; j < rowNum; ++j)
	{
		numberLeftCurLine = numbers[index];
		++index;
		for (int i = 0; i < columnNum; ++i)
		{
			if (numberLeftCurLine > 0)
			{
				core (i, j) = numbers[index];
				++index;
				--numberLeftCurLine;
			}
			else // fill zero
			{
				core (i, j) = 0;
			}
		}
	}

	_pCurAction->setFilterMethod (new FilterLinear (core));

	emit repaintViewport ();

}
